package com.dycong.common.transactionalTemplate;

import lombok.extern.log4j.Log4j2;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author arlain
 */
@Log4j2
public abstract class AbstractTransactionalTemplate<T, R> {


    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    public T doTransactional(R r) {
        int rows = Integer.MIN_VALUE;
        try {

            T t = queryLock(r);

            t = check(t, r);

            rows = update(t);

            return t;
        } catch (Throwable t) {
            log.error("事务异常，r:{},t:{},rows:{}", r, t, rows);
            throw t;
        }
    }

    /**
     * 一锁
     *
     * @param r
     * @return
     */
    abstract T queryLock(R r);

    /**
     * 二判
     *
     * @param t
     * @return
     */
    abstract T check(T t, R r);

    /**
     * 三更新
     *
     * @param t
     * @return
     */
    abstract int update(T t);

}
